iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0

偽類 (pseudo class) 是一種特別的 CSS 語法,它只會在指定的條件下生效。例如最常見的滑鼠移到 HTML 元素上時讓文字變色、底色變色,這種產生的 :hover 效果,就是一種偽類。

至於被稱為偽類的由來不得而之,筆者猜測,可能是這種 CSS 語法是必須在指定的條件下生效,而不是像一般的 CSS class 一樣,只要寫上去就會生效,就像是假的類別一樣,所以才被稱作「偽類」。


性質分類

依照 W3C 文件分類,偽類可依性質分為以下幾種:

  • 動態偽類 (dynamic pseudo-classes)
  • 目標偽類 (target pseudo-class)
  • 語言偽類 (language pseudo-class)
  • UI 元素狀態偽類 (UI element states pseudo-classes)
  • 結構偽類 (structural pseudo-classes)
  • 反項偽類 (negation pseudo-classes)

以下筆者整理的表格中,點選選擇器一欄的連結,可直接連到 MDN 或 W3C 的專屬文件網頁,有比較詳細的介紹。

動態偽類

選擇器 性質 用途 / 生效條件
:link 連結 在瀏覽器歷史記錄中,使用者尚未點擊過的連結。
:visited 連結 在瀏覽器歷史記錄中,使用者已拜訪過的連結。
:hover 動作 使用者的滑鼠移動到元素上。
:active 動作 使用者的滑鼠點擊元素。
:focus 動作 讓元素得到焦點時觸發,例如。點擊文字輸入框。

目標偽類

選擇器 用途 / 生效條件
:target 瀏覽器網址的 # 錨點與網頁元素內的 id 相同時會產生效果。可用來強調、突顯段落標題。

語言偽類

選擇器 用途 / 生效條件
:lang(language) 搭配網頁元素中帶有 lang 語言屬性產生效果。「language」代表語言代碼,例如 en

UI 元素狀態偽類

選擇器 用途 / 生效條件
:enabled 網頁元素禁止選取,例如 <input> 的 radio 或 checkobx、<select> 的 option 被禁止選取時。
:disabled 網頁元素禁止選取,例如 <input> 的 radio 或 checkobx、<select> 的 option 被禁止選取時。
:checked 例如 <input> 的 radio 或 checkobx、<select> 的 option 被選取時。

結構偽類

選擇器 用途 / 生效條件
:root 代表根元素,也就是 <html> 標籤。
:nth-child(n) 從每組兄弟元素從中選擇第 n 個節點。
:nth-last-child(n) :nth-child 相反,它是從最後一個兄弟元素往前計算。
:nth-of-type(n) 在從相同類型的每组兄弟元素中選擇第 n 個節點。
:nth-last-of-type(n) :nth-of-type 相反,它是從相同類型的每组兄弟元素中,從該組最後一個元素往前推算。
:first-child 從一組兄弟元素從中選擇第 1 個節點。
:last-child 從一組兄弟元素從中選擇第最後一個節點。
:first-of-type 在每组兄弟元素中選擇第 1 個節點。
:last-of-type 在每组兄弟元素中選擇最後個節點。
:only-child 沒有任何兄弟元素的節點。
:only-of-type 沒有其它相同類型的兄弟元素的節點。
:empty 沒有內容的節點。(可以只有注解標謙)

表格中的 「n」代表選取的條件,最簡單的條件下它是它是一個從數字 1 開始的順序數字,有更複雜的條件,再請點選連結閱讀文件。

反項偽類

選擇器 用途 / 生效條件
:not(selector) :not 指定的選擇器條件的元素會被排除,其餘元素會套用效果。「selector」代表選擇器條件。

範例準備

範例 10-0 原始碼
查看範例

這裡是本次範例的基礎原始碼,HTML 基本上不會修改,會變動的部分只有第 15 行的地方,會把每個範例增加的範例放在這裡。

範例網頁畫面
圖 a: 範例網頁畫面

原始的範例網頁看起來如上圖。是兩首詩,張繼的楓橋夜泊,以及文天祥的過零丁洋。

範例

偽類只要掌握使用方法,就能很快上手。這邊只挑選可能在使用時機上會有疑慮的出來說明。

  • nth-child
  • nth-of-type

nth-child

範例 10-1 原始碼
查看範例 10-1

第 3 行:選取奇數行,文字變紅色。
第 7 行:選取偶數行,文字變藍色。
第 11 行:選取第一行,文字加底線。

範例 10-1 網頁畫面
圖 b: 範例 10-1 網頁畫面

有沒有發現那裡怪怪的?
第一眼就可能發現,.item:nth-child(1) 選擇器居然沒生效?

class 為 item 的「月落烏啼雙滿天」及「辛苦遭逢起一經,干戈寥落四周星」這兩行,並沒有加上底線。

問題原因

那是因為,nth-child 它會先找到它的父元素,然後從父元素往下找,第一個節點是 .item 才會生效。

.item:nth-child(2n+1) {
	color: red;
}

奇數行變成紅色,那沒問題,因為父元素下排序為奇數的節點,符合選擇器是 .item 就會生效。

我們將 HTML 改成以下,看看會發生什麼事。

範例 10-2 原始碼
查看範例 10-2

第 4 行:把原 class 為 author 改成 item

範例 10-2 網頁畫面
圖 c: 範例 10-2 網頁畫面

修改的部分生效了。同樣的,使用 nth-child 來把奇數行文字變紅色、偶數行文字變藍色,也必須符合這種先找父元素,再找父元素下的節點,找到後比對選擇器正確才套用的規則。

nth-of-type

第 3 行:選取奇數行,文字變紅色。
第 7 行:選取偶數行,文字變藍色。
第 11 行:選取第二行,文字加底線。

以上 CSS 樣式不變,我們來看看下面例子。

範例 10-3 原始碼
查看範例 10-3

它們唯一的差別是在作者那一行,一個使用的 HTML 的標籤是 <section>,另一個是使用 <div> 其餘不變。

範例 10-3 網頁畫面
圖 d: 範例 10-3 網頁畫面

都是使用相同的 CSS 語法,都是用 .item 這個 class 當選擇器元素,但是結果確是有很大的不同!

問題原因

那是因為,nth-of-type 中的「type」指的就是 HTML 標籤。
它會先找到它的父元素,然後從父元素往下找,雖然也是找 .item,但是會以 type 來分群組。

以第一段詩來說:

nth-of-type 的解讀會是:

第 3 行:選取 <section class="item"><div class="item"> 奇數行,文字變紅色。
第 7 行:選取 <section class="item"><div class="item"> 偶數行,文字變藍色。
第 11 行:選取 <section class="item"><div class="item"> 的第二行,文字加底線。

nth-child vs nth-of-type

  • nth-child:會先找到它的父元素,然後從父元素往下找,符合偽類條件的節點是指定選擇器才會生效。
  • nth-of-type:會先找到它的父元素,然後以標籤分群直接找符合條件的選擇器。

總結

筆者在學習 CSS 的過程中,只曾對 nth-childnth-of-type 有過疑問,猜想或許大部分的人可能也是如此,畢竟其它偽類語法只要查文件,通常可以直覺使用不會有差錯,但這兩種看似相同,但又不大一樣,特別提出來分享。

明天會暫時先離開 CSS 的世界,往 JavaScript 靠隴一些,來分享 JS 的監聽事件處理,要將「上一個」以及「下一個」按紐加上點擊事件,準備讓 Slider 開始「滑」起來。


文中範例可在 GitHub Page 閱讀。
原始碼可在 2022 鐵人賽專用 GitHub Repo 下載。


上一篇
Day 9 - CSS 偽元素 (Pseudo Element)
下一篇
Day 11 - HTML 事件屬性 (Event Attribute)
系列文
重造會 Slide 的輪子!深入 JavaScript、CSS 模組化設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言